Add support for client side graphics exposures in gdk_draw_drawable
authorAlexander Larsson <alexl@redhat.com>
Wed, 27 May 2009 15:08:09 +0000 (17:08 +0200)
committerAlexander Larsson <alexl@redhat.com>
Wed, 27 May 2009 15:10:32 +0000 (17:10 +0200)
gdk/gdkdraw.c
gdk/gdkdrawable.h
gdk/gdkpixmap.c
gdk/gdkwindow.c
gdk/quartz/gdkdrawable-quartz.c
gdk/win32/gdkdrawable-win32.c
gdk/x11/gdkdrawable-x11.c

index 8c5d4227ac260ed7b4e7ee3f2998dc5c16e165e3..321b883cb32dd7084865290e4fe0cd958010a623 100644 (file)
@@ -663,16 +663,18 @@ gdk_draw_drawable (GdkDrawable *drawable,
     composite_impl = GDK_WINDOW_OBJECT (src)->impl;
   else
     composite_impl = composite;
-  
+
   /* TODO: For non-native windows this may copy stuff from other overlapping
-     windows. We should clip that and clear that area in the destination instead. */
-  
-  GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite_impl,
+     windows. We should clip that and (for windows with bg != None) clear that
+     area in the destination instead. */
+
+  GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc,
+                                                   composite_impl, src,
                                                     xsrc - composite_x_offset,
                                                     ysrc - composite_y_offset,
                                                     xdest, ydest,
                                                     width, height);
-  
+
   g_object_unref (composite);
 }
 
index 50904fc2e74bc70f900d6bb41233ad14fadc48df..1d8d69471d7c93af4a909f504ca39691e8350072 100644 (file)
@@ -100,6 +100,7 @@ struct _GdkDrawableClass
   void (*draw_drawable)  (GdkDrawable  *drawable,
                          GdkGC        *gc,
                          GdkDrawable  *src,
+                         GdkDrawable  *original_src,
                          gint          xsrc,
                          gint          ysrc,
                          gint          xdest,
index de735b91f0a3fc6ac765796fbb4efd56148c9e14..e4d8869286b5ac3118c0922900e9f5a0e26df7bf 100644 (file)
@@ -72,6 +72,7 @@ static void   gdk_pixmap_draw_text_wc   (GdkDrawable     *drawable,
 static void   gdk_pixmap_draw_drawable  (GdkDrawable     *drawable,
                                         GdkGC           *gc,
                                         GdkPixmap       *src,
+                                        GdkPixmap       *original_src,
                                         gint             xsrc,
                                         gint             ysrc,
                                         gint             xdest,
@@ -374,6 +375,7 @@ static void
 gdk_pixmap_draw_drawable (GdkDrawable *drawable,
                          GdkGC       *gc,
                          GdkPixmap   *src,
+                         GdkPixmap   *original_src,
                          gint         xsrc,
                          gint         ysrc,
                          gint         xdest,
index 1f2388b60f7b95e0236d74a5f14aab435bd5eedd..a2b5d6d618aff7ceb1c921706e815039a4249f36 100644 (file)
@@ -126,6 +126,7 @@ static void   gdk_window_draw_text_wc   (GdkDrawable     *drawable,
 static void   gdk_window_draw_drawable  (GdkDrawable     *drawable,
                                          GdkGC           *gc,
                                          GdkPixmap       *src,
+                                        GdkDrawable     *original_src,
                                          gint             xsrc,
                                          gint             ysrc,
                                          gint             xdest,
@@ -3426,6 +3427,7 @@ static void
 gdk_window_draw_drawable (GdkDrawable *drawable,
                          GdkGC       *gc,
                          GdkPixmap   *src,
+                         GdkDrawable *original_src,
                          gint         xsrc,
                          gint         ysrc,
                          gint         xdest,
@@ -3435,7 +3437,7 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
 {
   GdkWindowObject *private = (GdkWindowObject *)drawable;
   OFFSET_GC (gc);
-  
+
   if (GDK_WINDOW_DESTROYED (drawable))
     return;
 
@@ -3445,9 +3447,8 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
       GdkWindowPaint *paint = private->paint_stack->data;
       SETUP_PAINT_GC_CLIP (gc);
       gdk_draw_drawable (pixmap_impl (paint->pixmap), gc,
-                         src, xsrc, ysrc,
+                        src, xsrc, ysrc,
                         xdest - x_offset, ydest - y_offset, width, height);
-
       RESTORE_PAINT_GC_CLIP (gc);
     }
   else
@@ -3458,6 +3459,59 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
                         xdest - x_offset, ydest - y_offset,
                         width, height);
       RESTORE_DIRECT_GC_CLIP(gc);
+
+      /* We might have drawn from an obscured part of a client
+        side window, if so we need to send graphics exposures */
+      if (_gdk_gc_get_exposures (gc) &&
+         GDK_IS_WINDOW (original_src))
+       {
+         GdkRegion *exposure_region;
+         GdkRegion *clip;
+         GdkRectangle r;
+
+         r.x = xdest;
+         r.y = ydest;
+         r.width = width;
+         r.height = height;
+         exposure_region = gdk_region_rectangle (&r);
+
+         if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
+           clip = private->clip_region_with_children;
+         else
+           clip = private->clip_region;
+         gdk_region_intersect (exposure_region, clip);
+
+         clip = _gdk_gc_get_clip_region (gc);
+         if (clip)
+           {
+             gdk_region_offset (exposure_region,
+                                old_clip_x,
+                                old_clip_y);
+             gdk_region_intersect (exposure_region, clip);
+             gdk_region_offset (exposure_region,
+                                -old_clip_x,
+                                -old_clip_y);
+           }
+
+         /* Note: We don't clip by the clip mask if set, so this
+            may invalidate to much */
+
+         /* Remove the area that is correctly copied from the src.
+          * Note that xsrc/ysrc has been corrected for abs_x/y offsets already,
+          * which need to be undone */
+         clip = gdk_drawable_get_visible_region (original_src);
+         gdk_region_offset (clip,
+                            xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x),
+                            ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y));
+         gdk_region_subtract (exposure_region, clip);
+         gdk_region_destroy (clip);
+
+         gdk_window_invalidate_region (GDK_WINDOW (private),
+                                       exposure_region,
+                                       _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS);
+
+         gdk_region_destroy (exposure_region);
+       }
     }
 
   RESTORE_GC (gc);
@@ -5012,8 +5066,10 @@ gdk_window_invalidate_maybe_recurse (GdkWindow       *window,
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
-  
-  if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
+
+  if (private->input_only ||
+      !GDK_WINDOW_IS_MAPPED (window) ||
+      gdk_region_empty (region))
     return;
 
   visible_region = gdk_drawable_get_visible_region (window);
@@ -5086,7 +5142,7 @@ gdk_window_invalidate_maybe_recurse (GdkWindow       *window,
          gdk_window_schedule_update ((GdkWindow *)impl_window);
        }
     }
-  
+
   gdk_region_destroy (visible_region);
 }
 
index 72b678c0c5636d41bce5215905c3a73e53b6f296..673da0647710a49b55a59916e7838e8cf3f2eaab 100644 (file)
@@ -326,6 +326,7 @@ static void
 gdk_quartz_draw_drawable (GdkDrawable *drawable,
                          GdkGC       *gc,
                          GdkPixmap   *src,
+                         GdkDrawable *original_src,
                          gint         xsrc,
                          gint         ysrc,
                          gint         xdest,
index 4ccf0b3b605505bfc64fa6dfeb07eca7011485bf..18997ad0abdac092711146bd51a11fa139cfe0a4 100644 (file)
@@ -87,6 +87,7 @@ static void gdk_win32_draw_text_wc   (GdkDrawable    *drawable,
 static void gdk_win32_draw_drawable  (GdkDrawable    *drawable,
                                      GdkGC          *gc,
                                      GdkPixmap      *src,
+                                     GdkDrawable    *original_src,
                                      gint            xsrc,
                                      gint            ysrc,
                                      gint            xdest,
@@ -1143,6 +1144,7 @@ static void
 gdk_win32_draw_drawable (GdkDrawable *drawable,
                         GdkGC       *gc,
                         GdkPixmap   *src,
+                        GdkDrawable *original_src,
                         gint         xsrc,
                         gint         ysrc,
                         gint         xdest,
index e6ea4f1853e206bf5bb0a61f6ef7e47dd7a7d579..90d5c9e8a15bd22caa56a0c19ead2c2c54d5775a 100644 (file)
@@ -88,6 +88,7 @@ static void gdk_x11_draw_text_wc   (GdkDrawable    *drawable,
 static void gdk_x11_draw_drawable  (GdkDrawable    *drawable,
                                    GdkGC          *gc,
                                    GdkPixmap      *src,
+                                   GdkDrawable    *original_src,
                                    gint            xsrc,
                                    gint            ysrc,
                                    gint            xdest,
@@ -618,6 +619,7 @@ static void
 gdk_x11_draw_drawable (GdkDrawable *drawable,
                       GdkGC       *gc,
                       GdkPixmap   *src,
+                      GdkDrawable *original_src,
                       gint         xsrc,
                       gint         ysrc,
                       gint         xdest,